package camid.distribution.activeobject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;



public class ProxyExecutorManager {

	private static ProxyExecutorManager INSTANCE;
	
	public synchronized static ProxyExecutorManager getInstance() {
		if(INSTANCE == null)
		{
			INSTANCE = new ProxyExecutorManager();
		}
		return INSTANCE;
	}
	
	private Map<String, ExecutorService> proxyExecutors;
	
	private ProxyExecutorManager()
	{
		this.proxyExecutors = Collections.synchronizedMap(new HashMap<String, ExecutorService> ());
	}
	
	public ExecutorService getExecutor(String objectId)
	{	
		ExecutorService executor = null;
		if(!this.proxyExecutors.containsKey(objectId))
		{
			executor = Executors.newCachedThreadPool();
			this.proxyExecutors.put(objectId, executor);
		}
		else
		{
			executor = this.proxyExecutors.get(objectId);
		}
		return executor;
	}
	
	public void shutdownExecutors()
	{
		synchronized(proxyExecutors) 
		{
			for(Iterator<Entry<String,ExecutorService>> iterator = this.proxyExecutors.entrySet().iterator();
					iterator.hasNext();)
			{
				Entry<String,ExecutorService> entry = iterator.next();
				entry.getValue().shutdownNow();
				iterator.remove();
			}
		}
	}
	
	
	
	public void shutdownProxy(Object proxy)
	{
		if(Proxy.isProxyClass(proxy.getClass()))
		{
			InvocationHandler handler = Proxy.getInvocationHandler(proxy);
			if(handler instanceof RemoteInvocationHandler)
			{
				RemoteInvocationHandler remoteHandler = (RemoteInvocationHandler) handler;
				ExecutorService executor = this.proxyExecutors.get(remoteHandler.getObjectId());
				executor.shutdownNow();
				this.proxyExecutors.remove(remoteHandler.getObjectId());
			}
		}
	}
	
}
